﻿using System.Collections.Generic;
using System.Windows.Forms;
using System;
using System.Drawing;
using ZedGraph;
using com.foxmail.wyyuan1991.Assignment.Solver;
using com.foxmail.wyyuan1991.Assignment.Solver.Data;
using com.foxmail.wyyuan1991.Assignment.Host;

namespace com.foxmail.wyyuan1991.Assignment.WinForm
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private List<ArcLoadView> test()
        {
            INetwork net = DataGenerator.GenTestNetwork3();
            IDemand f = DataGenerator.GenTestFlow(net);

            //FWSolver s = new FWSolver()
            //{
            //    kesi = 0.000000000001M,//设置收敛阈值
            //    SA = new DijstraRouteSearcher(),
            //    LS = new DichotomyLineSearcher() { Kesi = 0.000000000000000001M }
            //};
            //IFlowDistribution ifd = s.Solve(net, f);

            SideConstraintSolver s = new SideConstraintSolver()
            {
                IterationUpbound = 99,
                Epsilon = 0.01,
                Sigema = 9,
                Beta = 0.25,
                Alpha = 5,
                SA = new DijstraRouteSearcher(),
                AS = new AoNSolver() { SA = new DijstraRouteSearcher() },
                LS = new DichotomyLineSearcher() { Kesi = 0.0000000000001 }
            };
            s.AFEvent += S_AFEvent;
            List<SideConstraint> SCList = new List<SideConstraint>();
            SideConstraint c;
            foreach (IArc a in net.ArcList)
            {
                if (a.Capacity <= 0) continue;
                c = new SideConstraint()
                {
                    LMF = delegate (IFlowPattern fa)
                    {
                        return fa.getFlow(a) - a.Capacity;
                    }
                };
                c[a] = ((IFlowPattern fa) => 1);
                c.Name = a.ID + "容量约束";
                SCList.Add(c);
            }

            c = new SideConstraint()
            {
                LMF = delegate (IFlowPattern fa)
                {
                    return fa.getFlow(net.ArcList[0]) + fa.getFlow(net.ArcList[1]) - 2;
                }
            };
            c[net.ArcList[0]] = ((IFlowPattern fa) => 1);
            c[net.ArcList[1]] = ((IFlowPattern fa) => 1);

            SCList.Add(c);

            IFlowPattern ifd = s.Solve(net, f, SCList);

            List<ArcLoadView> AlvList = new List<ArcLoadView>();

            foreach (IArc a in net.ArcList)
            {
                AlvList.Add(new ArcLoadView()
                {
                    Arc = a.ToString(),
                    Load = ifd.getFlow(a),
                    Cost = a.PerformaceFunction(ifd.getFlow(a))
                });
            }
            return AlvList;
        }

        private void S_AFEvent(object sender, ALSIterationFinishedEventArgs e)
        {
            Console.WriteLine("完成第{0}次迭代!", e.Itera);
            Console.WriteLine("罚值为：{0}", e.Penalty);
            Console.WriteLine("改进为：{0}", e.Evalution);
        }

        private void Form1_Shown(object sender, EventArgs e)
        {
            //DrawTest();
            this.bindingSource1.DataSource = test();
        }

        private void DrawTest()
        {
            z1.IsShowPointValues = true;
            //z1.GraphPane.Title = "Test Case for C#";
            double[] x = new double[100];
            double[] y = new double[100];
            int i;
            for (i = 0; i < 100; i++)
            {
                x[i] = (double)i / 100.0 * Math.PI * 2.0;
                y[i] = Math.Sin(x[i]);
            }
            z1.GraphPane.AddCurve("Sine Wave", x, y, Color.Red, SymbolType.Square);
            z1.AxisChange();
            z1.Invalidate();
        }

        // Starting time in milliseconds
        int tickStart = 0;
        private void timer1_Tick(object sender, EventArgs e)
        {
            //确保CurveList不为空
            if (z1.GraphPane.CurveList.Count <= 0)
            {
                return;
            }

            //取Graph第一个曲线，也就是第一步:在GraphPane.CurveList集合中查找CurveItem
            LineItem curve = z1.GraphPane.CurveList[0] as LineItem;
            if (curve == null)
            {
                return;
            }

            //第二步:在CurveItem中访问PointPairList(或者其它的IPointList)，根据自己的需要增加新数据或修改已存在的数据
            //IPointListEdit list = curve.Points as IPointListEdit;
            // If this is null, it means the reference at curve.Points does not
            // support IPointListEdit, so we won't be able to modify it
            //if (list == null)
            //{
            //    return;
            //}

            // Time is measured in seconds
            double time = (Environment.TickCount - tickStart) / 1000.0;

            // 3 seconds per cycle
            //list.Add(time, Math.Sin(2.0 * Math.PI * time / 3.0));

            // Keep the X scale at a rolling 30 second interval, with one
            // major step between the max X value and the end of the axis
            Axis xScale = z1.GraphPane.XAxis;
            //if (time > xScale.Max - xScale.Step)
            //{
            //    xScale.Max = time + xScale.Step;
            //    xScale.Min = xScale.Max - 30.0;
            //}

            //第三步:调用ZedGraphControl.AxisChange()方法更新X和Y轴的范围
            z1.AxisChange();

            //第四步:调用Form.Invalidate()方法更新图表
            z1.Invalidate();
        }
    }

}
